﻿using GeekTime.Domain;
using GeekTime.Domain.Abstructions;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Threading.Tasks;

namespace GeekTime.Infrastructure.Core.Extensions
{
    static class MediatorExtension
    {
        public static async Task DispatchDomainEventsAsync(this IMediator mediator, DbContext ctx)
        {
            //从当前的entityContext中跟踪实体，从跟踪到的实体的对象中获取当前的Event 
            var domainEntities = ctx.ChangeTracker
                .Entries<Entity>()
                .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());

            //如果Event存在  那就把这个Event取出
            var domainEvents = domainEntities
                .SelectMany(x => x.Entity.DomainEvents)
                .ToList();

            //ranhou  把实体内的event清除
            domainEntities.ToList()
                .ForEach(entity => entity.Entity.ClearDomainEvents());

            //然后将event逐条的通过中间者发送出去。
            //将领域事件发出，并且找到对应的handler进行处理
            foreach (var domainEvent in domainEvents)
                await mediator.Publish(domainEvent);
        }
    }
}
